home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*------------------------------------------------------------------------------
- *
- * OORT - gameio.c - Routines for game i/o.
- *
- * $Id: gameio.c,v 1.4 1994/01/28 00:18:20 mtj Exp $
- *
- * Chris Fouts - May, 1993.
- *
- *----------------------------------------------------------------------------*/
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <string.h>
- #include <netdb.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
-
- #include <Performer/pf.h>
-
- #include "oort.h"
- #include "gameio.h"
- #include "dashboard.h"
- #include "explosion.h"
- #include "sound.h"
- #include "multicast.h"
-
- #define MAX_ACTIVITY 100
- #define END_OF_FRAME (-1)
-
-
- /* BEGIN PROTOTYPES -S gameio.c */
- static void demoIn( void ) ;
- static void displayNotice( Notice *notice ) ;
- static void fileIn( void ) ;
- static void fileOut( void ) ;
- static void initializeInputFile( char *name ) ;
- static void initializeNetwork( char *servName, int defaultPort ) ;
- static void initializeOutputFile( char *name ) ;
- static void networkIn( void ) ;
- static void networkOut( void ) ;
- static void noOp( void ) ;
- static void processPlayerPacket( Player *input ) ;
- static void processPlayers( void ) ;
- static void processSelfInDemo( Player *input ) ;
- static int readRestOfFilePacket( void *packet, int size ) ;
- static void setName( void ) ;
- static void updatePlayers( void ) ;
- /* END PROTOTYPES -S gameio.c */
-
- /*
- * The following is not prototyped anywhere.
- */
- long gethostid( void ) ;
-
-
-
- extern int freezeTape ;
- extern int timeToLive ;
- extern int inFd ;
- extern int outFd ;
- extern int numberPlayers ;
- extern int activity[] ;
- extern int networking ;
- extern int demoMode ;
- extern int debugOn ;
- extern int selfStatus ;
- extern int newSelfStatus ;
- extern char *basename ;
- extern char playerName[] ;
- extern pfMatrix playerMatrix[] ;
- extern pfGroup *vehicle[N_TEAMS] ;
- extern pfDCS *trike[] ;
- extern pfGroup *trikeSwitch[] ;
- extern pfGroup *shield ;
- extern char *inName ;
- extern char *outName ;
- extern float gameTime ;
- extern float eTime ;
- extern float speed ;
- extern float power ;
- extern float shields ;
- extern float laser ;
- extern float laserCharge ;
- extern float topSpeed ;
- extern Player player[] ;
- extern float deadTime[] ;
- extern pfVec3 ahead ;
- extern pfVec3 up ;
- extern pfVec3 right ;
- extern pfVec3 velocity[] ;
- extern pfVec3 acceleration[] ;
- extern Motion motion ;
- extern PacketFunction readPackets ;
- extern PacketFunction writePackets ;
-
- static struct sockaddr_in inAddr ;
- static struct sockaddr_in outAddr ;
-
- static float tStamp = 0.0f ;
-
-
- /*------------------------------------------------------------------------------
- * Output player positions to a file.
- *----------------------------------------------------------------------------*/
- static void
- fileOut(
- void
- )
- {
- int i ;
- ngMagic eof = END_OF_FRAME ;
-
- PFCOPY_VEC3( player[SELF].ahead, ahead ) ;
- PFCOPY_VEC3( player[SELF].right, right ) ;
- PFCOPY_VEC3( player[SELF].up, up ) ;
- player[SELF].time = speed / topSpeed ;
-
- player[SELF].status = ( player[SELF].status & 0x0f0 ) | selfStatus ;
-
- if( write( outFd, (void *)&eof, sizeof( eof ) ) < sizeof( eof ) )
- {
- perror( outName ) ;
- endProgram( 0 ) ;
- }
-
- if( write( outFd, (void *)&gameTime, sizeof( gameTime ) ) <
- sizeof( gameTime ) )
- {
- perror( outName ) ;
- endProgram( 0 ) ;
- }
-
- for( i = numberPlayers ; i-- ; )
- {
- if( write( outFd, (void *)( &player[i] ), sizeof( Player ) ) <
- sizeof( Player ) )
- {
- perror( outName ) ;
- endProgram( 0 ) ;
- }
- }
-
- player[SELF].hitId = 0 ;
- player[SELF].laserStrength = 0 ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Read of frame of players packets from a file.
- *----------------------------------------------------------------------------*/
- static void
- fileIn(
- void
- )
- {
- int noCharsRead ;
- GamePacket packet ;
- Player input ;
- int st = 0 ;
- int i ;
- int number ;
- static float loopTime = 0.0f ;
-
- if( freezeTape )
- {
- loopTime += eTime ;
- tStamp += eTime ;
- return ;
- }
-
- while( gameTime > tStamp )
- {
- i = 0 ;
- do
- {
- if( ( noCharsRead = read( inFd, &(packet.magic),
- sizeof( packet.magic ) ) ) ==
- sizeof( packet.magic ) )
- {
- switch( packet.magic )
- {
- case OORT_PLAYER :
- if( !( st = readRestOfFilePacket(
- &packet,
- sizeof( packet.player ) ) ) )
- {
- packet.player.id++ ;
- if( ngValidKeyedHost(
- packet.player.id,
- packet.player.key ) )
- {
- processPlayerPacket(
- &(packet.player) ) ;
- }
- }
- break ;
-
- case OORT_NOTICE :
- if( !( st = readRestOfFilePacket(
- &packet,
- sizeof( packet.notice ) ) ) )
- {
- if( ngValidKeyedHost(
- packet.notice.id,
- packet.notice.key ) )
- {
- displayNotice(
- &packet.notice ) ;
- }
- }
- break ;
-
- case END_OF_FRAME :
- i = 1 ;
- break ;
-
- default :
- fprintf( stderr, "%s: unknown packet "
- "type received in %s.\n",
- basename, inName ) ;
- endProgram( 1 ) ;
- break ;
- }
- if( st )
- {
- fprintf( stderr, "%s: bad packet read "
- "from %s.\n", basename,
- inName ) ;
- endProgram( 1 ) ;
- }
- }
- else if( noCharsRead == 0 )
- {
- noCharsRead = sizeof( tStamp ) +
- sizeof( ngMagic ) ;
- if( lseek( inFd, noCharsRead, SEEK_SET )
- != noCharsRead )
- {
- readPackets = noOp ;
- fprintf( stderr, "%s: could not rewind "
- "`%s'.\n", basename, inName ) ;
- }
- /*
- * If we loop through the file, need to
- * adjust the time stamp next time through by
- * the current time stamp.
- */
- loopTime = tStamp ;
- postNewMessage( "End of input file." ) ;
- while( numberPlayers > 1 )
- {
- deletePlayer( numberPlayers-1,
- "was deleted" ) ;
- }
- }
- else
- {
- perror( inName ) ;
- endProgram( 1 ) ;
- }
- } while( i == 0 ) ;
-
- processPlayers() ;
-
- if( read( inFd, &tStamp, sizeof( tStamp ) ) < sizeof( tStamp ) )
- {
- perror( inName ) ;
- endProgram( 1 ) ;
- }
- else
- {
- tStamp += loopTime ;
- }
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * No op function.
- *----------------------------------------------------------------------------*/
- static void
- noOp(
- void
- )
- {
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Read the remainder of a game packet.
- *----------------------------------------------------------------------------*/
- static int
- readRestOfFilePacket(
- void *packet,
- int size
- )
- {
- int ncRead ;
-
- size -= sizeof( ngMagic ) ;
-
- if( ( ncRead = read( inFd, (char *)packet + sizeof( ngMagic ), size ) )
- != size )
- {
- return( ncRead ) ;
- }
- else
- {
- return( 0 ) ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Process a player packet.
- *----------------------------------------------------------------------------*/
- static void
- processPlayerPacket(
- Player *input
- )
- {
- int number ;
- int killer ;
- float dt ;
- pfNode *oldRave ;
-
- /*
- * Either update existing player or create a new one
- */
- if( !( number = findPlayer( input->id ) ) )
- {
- if( demoMode && input->id == player[SELF].id )
- {
- processSelfInDemo( input ) ;
- return ;
- }
- else
- {
- number = addPlayer( input ) ;
- postNewMessage( "Added %s", input->name ) ;
- checkId( number ) ;
- }
- }
-
- activity[number] = MAX_ACTIVITY ;
-
- /*
- * See if status changed.
- */
- if( player[number].status != input->status )
- {
- /*
- * Check for shield on going on.
- */
- if( !SHIELD_ON( player+number ) && SHIELD_ON( input ) )
- {
- if( pfGetNumChildren( trikeSwitch[number] ) > 1 )
- {
- pfNodeTravMask(
- pfGetChild( trikeSwitch[number], 1 ),
- PFTRAV_DRAW, 0xffffffff, PFTRAV_SELF,
- PF_SET ) ;
- }
- }
-
- /*
- * Check for starting to explode.
- */
- if( !EXPLODING( player+number ) && EXPLODING( input ) )
- {
- startExplosion( number ) ;
- if( input->hitById == player[SELF].id )
- {
- player[SELF].score += 1 ;
- postNewMessage( "Killed %s.", input->name ) ;
- addKill() ;
- }
- else if( input->hitById == 0 &&
- readPackets == networkIn )
- {
- postNewMessage( "%s killed by orbital "
- "fortress.", input->name ) ;
- }
- else
- {
- postNewMessage( "%s is dead.", input->name ) ;
- }
- }
- /*
- * Check for stopping explosion.
- */
- else if( EXPLODING( player+number ) && !EXPLODING( input ) )
- {
- endExplosion( number ) ;
- }
- /*
- * Check for beginning to land.
- */
- if( ( player[number].status & OORT_ST_IN_ORBIT ) &&
- ( input->status & OORT_ST_ON_GROUND ) )
- {
- PFSET_VEC3( acceleration[number], 0.0f, 0.0f, 0.0f ) ;
- PFSET_VEC3( velocity[number], 0.0f, 0.0f, 0.0f ) ;
- }
- }
-
- /*
- * See if team changed.
- */
- if( player[number].team != input->team )
- {
- oldRave = pfGetChild( trikeSwitch[number], 0 ) ;
- if( pfReplaceChild( trikeSwitch[number], oldRave,
- pfClone( vehicle[input->team], 0 ) ) )
- {
- pfDelete( oldRave ) ;
- postNewMessage( "%s changed teams.", input->name ) ;
- }
- else
- {
- postNewMessage( "%s changed teams (err).",
- input->name ) ;
- }
- }
-
- /*
- * Check to see if enemy hit me.
- */
- if( input->hitId == player[SELF].id )
- {
- shieldDamage( (float)input->laserStrength / 255.0f, input->id );
- }
-
- /*
- * Check for collision.
- */
- if( selfStatus == OORT_ST_ON_GROUND && !EXPLODING( input ) )
- {
- if( pfSqrDistancePt3( player[SELF].xyz, input->xyz ) <
- (float)(4.0f * SHIELD_RADIUS * SHIELD_RADIUS ) )
- {
- postNewMessage( "Collided with %s.", input->name ) ;
- shieldDamage( 0.75f, input->id ) ;
- speed *= 0.5f ;
- }
- }
-
- /*
- * Compute velocity for player in an effort to smooth animation
- * (this is a pretty cheesy attempt).
- */
- if( readPackets == networkIn )
- {
- float elapsedTime ;
- float sf ;
- pfVec3 newVel ;
-
- elapsedTime = input->time - player[number].time ;
- if( elapsedTime > 0.0f )
- {
- sf = 0.8f / elapsedTime ;
- }
- else
- {
- sf = 0.0f ;
- }
- PFSUB_VEC3( newVel, input->xyz, player[number].xyz ) ;
- PFSCALE_VEC3( newVel, sf, newVel ) ;
- PFSUB_VEC3( acceleration[number], newVel, velocity[number] ) ;
- PFSCALE_VEC3( acceleration[number], sf, acceleration[number] ) ;
- PFCOPY_VEC3( velocity[number], newVel ) ;
- }
- else
- {
- float sf ;
-
- sf = 0.8f / eTime ;
- PFSUB_VEC3( velocity[number], input->xyz, player[number].xyz ) ;
- PFSCALE_VEC3( velocity[number], sf, velocity[number] ) ;
- }
-
- /*
- * Update player.
- */
- copyPlayer( number, input ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Initialize for reading packets from a file.
- *----------------------------------------------------------------------------*/
- static void
- initializeInputFile(
- char *name
- )
- {
- ngMagic magic ;
-
- if( ( inFd = open( name, O_RDONLY ) ) == -1 )
- {
- perror( name ) ;
- endProgram( 1 ) ;
- }
- else
- {
- /*
- * Read in first end-of frame marker.
- */
- if( read( inFd, &magic, sizeof( magic ) ) != sizeof( magic ) )
- {
- perror( name ) ;
- endProgram( 1 ) ;
- }
-
- if( read( inFd, &tStamp, sizeof(tStamp) ) != sizeof(tStamp) )
- {
- perror( name ) ;
- endProgram( 1 ) ;
- }
-
- if( read( inFd, &magic, sizeof( magic ) ) != sizeof( magic ) )
- {
- perror( name ) ;
- endProgram( 1 ) ;
- }
-
- if( magic != OORT_PLAYER )
- {
- fprintf( stderr, "%s: input file `%s' is not from this"
- " version of %s.\n", basename, name,
- basename ) ;
- endProgram( 1 ) ;
- }
- else
- {
- lseek( inFd, -sizeof( tStamp ), SEEK_CUR ) ;
- }
- }
- readPackets = ( demoMode ) ? demoIn : fileIn ;
-
- if( demoMode )
- {
- postNewMessage( "Demo mode." ) ;
- }
- tStamp = 0.0f ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Initialize for recording packets to a file.
- *----------------------------------------------------------------------------*/
- static void
- initializeOutputFile(
- char *name
- )
- {
- if( ( outFd = open( name, O_WRONLY|O_CREAT|O_TRUNC, 0644 ) ) == -1 )
- {
- perror( name ) ;
- endProgram( 1 ) ;
- }
- writePackets = fileOut ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Initialize the communication routines.
- *----------------------------------------------------------------------------*/
- void
- initCom(
- void
- )
- {
- int i ;
- int port ;
- struct servent *serv ;
-
- networking = 0 ;
-
- if( inName == NULL && outName == NULL )
- {
- networking = 1 ;
- initializeNetwork( OORT_SERVICE, OORT_DEF_PORT ) ;
- }
- else
- {
- if( inName != NULL )
- {
- initializeInputFile( inName ) ;
- }
- else
- {
- readPackets = noOp ;
- inFd = -1 ;
- }
-
- if( outName != NULL )
- {
- initializeOutputFile( outName ) ;
- }
- else
- {
- writePackets = noOp ;
- outFd = -1 ;
- }
- }
-
- if( networking )
- {
- player[SELF].id = gethostid() ;
- }
- else {
- player[SELF].id = 1 ;
- }
-
- setName() ;
-
- ngInit( player[SELF].id, player[SELF].key, player[SELF].name,
- OORT_DROP, OORT_INVALIDATE, OORT_CENSUS, OORT_ACK, OORT_QUIT,
- "/usr/tmp/oort.log" ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Process the players.
- *----------------------------------------------------------------------------*/
- static void
- processPlayers(
- void
- )
- {
- int i ;
-
- for( i = ENEMY ; i < numberPlayers ; i++ )
- {
- activity[i] -= 1 ;
- if( activity[i] < 0 )
- {
- ngDropHost( player[i].id ) ;
- deletePlayer( i, "was dropped" ) ;
- }
-
- playerMatrix[i][0][0] = player[i].right[0] ;
- playerMatrix[i][0][1] = player[i].right[1] ;
- playerMatrix[i][0][2] = player[i].right[2] ;
-
- playerMatrix[i][1][0] = player[i].ahead[0] ;
- playerMatrix[i][1][1] = player[i].ahead[1] ;
- playerMatrix[i][1][2] = player[i].ahead[2] ;
-
- playerMatrix[i][2][0] = player[i].up[0] ;
- playerMatrix[i][2][1] = player[i].up[1] ;
- playerMatrix[i][2][2] = player[i].up[2] ;
-
- playerMatrix[i][3][0] = player[i].xyz[0] ;
- playerMatrix[i][3][1] = player[i].xyz[1] ;
- playerMatrix[i][3][2] = player[i].xyz[2] ;
-
- pfDCSMat( trike[i], playerMatrix[i] ) ;
-
- if( EXPLODING( player+i ) )
- {
- setExplosionFrame( i, gameTime - deadTime[i] ) ;
- }
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Set the player name.
- *----------------------------------------------------------------------------*/
- static void
- setName(
- void
- )
- {
- char *name ;
-
- if( strlen( playerName ) == 0 )
- {
- if( ( name = getenv( "OORT_ID" ) ) != NULL )
- {
- strncpy( playerName, name, NAMELEN ) ;
- }
- else
- {
- cuserid( playerName ) ;
- }
- }
- strncpy( player[SELF].name, playerName, NAMELEN ) ;
- player[SELF].name[NAMELEN-1] = '\0' ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Send out a packet, either to the net, to a file, or nothting.
- *----------------------------------------------------------------------------*/
- void
- sendOut(
- void *buf,
- int size
- )
- {
- if( writePackets == networkOut )
- {
- sendToNetwork( buf, size ) ;
- }
- else if( writePackets == fileOut )
- {
- sendToFile( buf, size ) ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Write a packet to a file.
- *----------------------------------------------------------------------------*/
- void
- sendToFile(
- void *buf,
- int size
- )
- {
- int noCharsSent ;
-
- noCharsSent = write( outFd, buf, size ) ;
- if( noCharsSent < size )
- {
- perror( "sendToFile" ) ;
- endProgram( 0 ) ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Write a packet to the network.
- *----------------------------------------------------------------------------*/
- void
- sendToNetwork(
- char *buf,
- int size
- )
- {
- int noCharsSent ;
-
- noCharsSent = sendto( outFd, buf, size, 0, &outAddr, sizeof(outAddr) ) ;
- if( noCharsSent < size ) {
- perror( "sendToNetwork" ) ;
- endProgram( 0 ) ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Write packets out to network.
- *----------------------------------------------------------------------------*/
- static void
- networkOut(
- void
- )
- {
- int noCharsSent ;
-
- PFCOPY_VEC3( player[SELF].ahead, ahead ) ;
- PFCOPY_VEC3( player[SELF].right, right ) ;
- PFCOPY_VEC3( player[SELF].up, up ) ;
- player[SELF].time = gameTime ;
-
- noCharsSent = sendto( outFd, (char *)(&player[SELF]),
- sizeof( Player ), 0, &outAddr, sizeof( outAddr ) ) ;
- if( noCharsSent < sizeof( Player ) ) {
- perror( "networkOut" ) ;
- endProgram( 0 ) ;
- }
-
- player[SELF].hitId = 0 ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Initialize the network for multicasting.
- *----------------------------------------------------------------------------*/
- static void
- initializeNetwork(
- char *servName,
- int defaultPort
- )
- {
- int port ;
- struct servent *serv ;
-
- if( ( serv = getservbyname( servName, NULL ) ) == NULL )
- {
- fprintf( stderr, "Can't find udp service \"%s\"\n", servName ) ;
- fprintf( stderr, "To run over the network, you must have the "
- "following line\n" ) ;
- fprintf( stderr, "in your /etc/services file.\n\n" ) ;
- fprintf( stderr, "%s\t%d/udp\n\n", servName, defaultPort ) ;
- port = defaultPort ;
- }
- else
- {
- port = serv->s_port ;
- }
-
- if( timeToLive < NG_MIN_TTL || timeToLive > NG_MAX_TTL )
- {
- fprintf( stderr, "Specified time-to-live (%d) does not fall "
- "within acceptable range (%d - %d).\n", timeToLive,
- NG_MIN_TTL, NG_MAX_TTL ) ;
- fprintf( stderr, "The default value of %d will be used.\n",
- NG_DEFAULT_TTL ) ;
- timeToLive = NG_DEFAULT_TTL ;
- }
-
- if( ( inFd = openMulticastSocket( &inAddr, port, timeToLive, 0,
- OORT_GROUP, NULL, "r" ) ) < 0 )
- {
- endProgram( 1 ) ;
- }
- readPackets = networkIn ;
-
- /*
- * Turn on non-blocking I/O
- */
- if( fcntl( inFd, F_SETFL, FNDELAY ) < 0 ) {
- perror( "fcntl F_SETFL, FNDELAY" ) ;
- endProgram( 1 ) ;
- }
-
- if( ( outFd = openMulticastSocket( &outAddr, port, timeToLive, 0,
- OORT_GROUP, NULL, "w" ) ) < 0 )
- {
- endProgram( 1 ) ;
- }
- writePackets = networkOut ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Read packets from the network.
- *----------------------------------------------------------------------------*/
- static void
- networkIn(
- void
- )
- {
- int noCharsReceived ;
- int id ;
- GamePacket packet ;
- int st = 0 ;
- int number ;
- int inAddrLen ;
- int socket_empty = 0 ;
- static int newer = 0 ;
-
- updatePlayers() ;
-
- while( !socket_empty ) {
- noCharsReceived = recvfrom( inFd, (char *)(&packet),
- sizeof(GamePacket), 0, &inAddr, &inAddrLen ) ;
- if( noCharsReceived < 0 && errno == EWOULDBLOCK )
- {
- socket_empty = 1 ;
- }
- else
- {
- switch( packet.magic )
- {
- case OORT_PLAYER :
- if( noCharsReceived == sizeof( packet.player ) )
- {
- if( ngValidHost( packet.player.id ) )
- {
- processPlayerPacket(
- &(packet.player) ) ;
- }
- /*
- * New player, send out acknowledge
- * packet.
- */
- else if( numberPlayers < MAXPLAYERS )
- {
- ngAcknowledge( packet.player.id,
- packet.player.key ) ;
- }
- }
- else
- {
- st = sizeof( packet.player ) ;
- }
- break ;
-
- case OORT_QUIT :
- if( noCharsReceived == sizeof( struct ngAck ) )
- {
- number = findPlayer( packet.ack.id ) ;
- if( number > 0 )
- {
- ngRemoveHost( packet.ack.id ) ;
- deletePlayer( number, "quit" ) ;
- }
- else
- {
- ngQuitHost( packet.ack.id ) ;
- }
- }
- else
- {
- st = sizeof( struct ngAck ) ;
- }
- break ;
-
- case OORT_ACK :
- if( noCharsReceived == sizeof( struct ngAck ) )
- {
- /*
- * If acknowledging SELF, add to list
- * of valid hosts.
- */
- if( packet.ack.ackId ==
- player[SELF].id )
- {
- ngValidKeyedHost( packet.ack.id,
- packet.ack.key ) ;
- ngAcknowledge( packet.player.id,
- packet.player.key ) ;
- }
- }
- else
- {
- st = sizeof( struct ngAck ) ;
- }
- break ;
-
- case OORT_DROP :
- if( noCharsReceived == sizeof( struct ngAck ) )
- {
- id = packet.ack.id ;
- /*
- * If dropping SELF, note dropped
- * status with host.
- */
- if( packet.ack.ackId ==
- player[SELF].id &&
- ngValidHost( id ) )
- {
- ngDroppedByHost( id ) ;
- number = findPlayer( id ) ;
- if( number > 0 )
- {
- deletePlayer( number,
- "was dropped" );
- }
- }
- }
- else
- {
- st = sizeof( struct ngAck ) ;
- }
- break ;
-
- case OORT_INVALIDATE :
- if( noCharsReceived == sizeof( struct ngAck ) )
- {
- id = packet.ack.id ;
- /*
- * If invalidating SELF, invalidate in
- * kind.
- */
- if( packet.ack.ackId ==
- player[SELF].id &&
- ngValidHost( id ) )
- {
- ngDprintf( "%s: got invalidate"
- " packet from %s\n",
- ngPrintTime(),
- ngHostNameFromId(id) ) ;
- ngInvalidateHost( id ) ;
- number = findPlayer( id ) ;
- if( number > 0 )
- {
- deletePlayer( number,
- "was dropped" );
- }
- }
- }
- else
- {
- st = sizeof( struct ngAck ) ;
- }
- break ;
-
- case OORT_NOTICE :
- if( noCharsReceived == sizeof( Notice ) )
- {
- if( ngValidKeyedHost(
- packet.notice.id,
- packet.notice.key ) )
- {
- displayNotice(
- &packet.notice ) ;
- }
- }
- else
- {
- st = sizeof( Notice ) ;
- }
- break ;
-
-
- default :
- if( packet.magic > OORT_PLAYER &&
- ( packet.magic & 0xffffff00 ) ==
- ( OORT_PLAYER & 0xffffff00) &&
- newer == 0 )
- {
- newer = 1 ;
- printf( "\n\nAn newer version of %s is"
- " being played on the net.\n\n",
- basename ) ;
- }
- break ;
- }
- if( st )
- {
- fprintf( stderr, "received odd packet size of "
- "%d instead of %d! (id = 0x%08x)\n",
- noCharsReceived, st, packet.magic ) ;
- st = 0 ;
- }
- }
- }
-
- processPlayers() ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Update players positions based on last computed velocity (allows smooth
- * movement between machines running at different framerates).
- *----------------------------------------------------------------------------*/
- static void
- updatePlayers(
- void
- )
- {
- int i ;
-
- for( i = ENEMY ; i < numberPlayers ; i++ )
- {
- player[i].xyz[0] += eTime * velocity[i][0] ;
- player[i].xyz[1] += eTime * velocity[i][1] ;
- player[i].xyz[2] += eTime * velocity[i][2] ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Read of frame of players packets from a file and set view to that of the
- * first vehicle.
- *----------------------------------------------------------------------------*/
- static void
- demoIn(
- void
- )
- {
- int noCharsRead ;
- GamePacket packet ;
- Player input ;
- int st = 0 ;
- int i ;
- int number ;
- static float loopTime = 0.0f ;
-
- if( freezeTape )
- {
- loopTime += eTime ;
- tStamp += eTime ;
- return ;
- }
-
- while( gameTime > tStamp )
- {
- i = 0 ;
- do
- {
- if( ( noCharsRead = read( inFd, &(packet.magic),
- sizeof( packet.magic ) ) ) ==
- sizeof( packet.magic ) )
- {
- switch( packet.magic )
- {
- case OORT_PLAYER :
- if( !( st = readRestOfFilePacket(
- &packet,
- sizeof( packet.player ) ) ) )
- {
- if( ngValidKeyedHost(
- packet.player.id,
- packet.player.key ) )
- {
- processPlayerPacket(
- &(packet.player) ) ;
- }
- }
- break ;
-
- case OORT_NOTICE :
- if( !( st = readRestOfFilePacket(
- &packet,
- sizeof( packet.notice ) ) ) )
- {
- if( ngValidKeyedHost(
- packet.notice.id,
- packet.notice.key ) )
- {
- displayNotice(
- &packet.notice ) ;
- }
- }
- break ;
-
- case END_OF_FRAME :
- i = 1 ;
- break ;
-
- default :
- fprintf( stderr, "%s: unknown packet "
- "type received in %s.\n",
- basename, inName ) ;
- endProgram( 1 ) ;
- break ;
- }
- if( st )
- {
- fprintf( stderr, "%s: bad packet read "
- "from %s.\n", basename,
- inName ) ;
- endProgram( 1 ) ;
- }
- }
- else if( noCharsRead == 0 )
- {
- noCharsRead = sizeof( tStamp ) +
- sizeof( ngMagic ) ;
- if( lseek( inFd, noCharsRead, SEEK_SET )
- != noCharsRead )
- {
- readPackets = noOp ;
- fprintf( stderr, "%s: could not rewind "
- "`%s'.\n", basename, inName ) ;
- }
- /*
- * If we loop through the file, need to
- * adjust the time stamp next time through by
- * the current time stamp.
- */
- loopTime = tStamp ;
- postNewMessage( "End of input file." ) ;
- while( numberPlayers > 1 )
- {
- deletePlayer( numberPlayers-1,
- "was deleted" ) ;
- }
- }
- else
- {
- perror( inName ) ;
- endProgram( 1 ) ;
- }
- } while( i == 0 ) ;
-
- processPlayers() ;
-
- if( ( noCharsRead = read( inFd, &tStamp, sizeof( tStamp ) ) )
- < sizeof( tStamp ) )
- {
- perror( inName ) ;
- endProgram( 1 ) ;
- }
- else
- {
- tStamp += loopTime ;
- }
- }
-
- PFCOPY_VEC3( motion.cg, player[SELF].xyz ) ;
- PFCOPY_VEC3( ahead, player[SELF].ahead ) ;
- PFCOPY_VEC3( right, player[SELF].right ) ;
- PFCOPY_VEC3( up, player[SELF].up ) ;
-
- newSelfStatus = player[SELF].status & 0x0f ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Process player packet for self in demo mode.
- *----------------------------------------------------------------------------*/
- static void
- processSelfInDemo(
- Player *input
- )
- {
- /*
- * Determine speed.
- */
- speed = player[SELF].time * topSpeed ;
-
- /*
- * Check for shield on going on.
- */
- if( !SHIELD_ON( player+SELF ) && SHIELD_ON( input ) )
- {
- shieldDamage( ( shields > 0.5f ) ? 0.5f : shields, 0 ) ;
- }
-
- /*
- * Check for starting to explode.
- */
- if( !EXPLODING( player+SELF ) && EXPLODING( input ) )
- {
- blowUpSelf( input->hitById ) ;
- }
-
- if( player[SELF].laserStrength )
- {
- sfx( SFX_FIRE ) ;
- if( laser > laserCharge )
- {
- laser -= laserCharge ;
- }
- else
- {
- laser = 0.0f ;
- }
- }
-
- copyPlayer( SELF, input ) ;
-
- return ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Send out a message.
- *----------------------------------------------------------------------------*/
- void
- mailMessage(
- char team,
- char *msg
- )
- {
- Notice notice ;
-
- notice.magic = OORT_NOTICE ;
- notice.id = player[SELF].id ;
- notice.key = player[SELF].key ;
- notice.team = team ;
- strncpy( notice.msg, msg, sizeof( notice.msg ) ) ;
- notice.msg[MAX_MSG_SIZE-1] = '\0' ;
-
- sendOut( ¬ice, sizeof( notice ) ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Display a notice that has arrived if it's addressed to me.
- *----------------------------------------------------------------------------*/
- static void
- displayNotice(
- Notice *notice
- )
- {
- int n ;
-
- n = findPlayer( notice->id ) ;
-
- if( notice->team == MAIL_ALL )
- {
- sfx( SFX_NEWMAIL ) ;
- postNewMessage( "Broadcast message from %s:", player[n].name ) ;
- }
- else if( notice->team == player[SELF].team )
- {
- sfx( SFX_NEWMAIL ) ;
- postNewMessage( "Team message from %s:", player[n].name ) ;
- }
- else
- {
- return ;
- }
-
- postNewMessage( "%s", notice->msg ) ;
- }
-